package org.groupg.practice;

import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultEdge;

import java.util.Set;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class GraphTaskExecution {

    public static void main(String[] args) {
        // 创建有向图
        Graph<String, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);

        // 添加节点
        graph.addVertex("A");graph.addVertex("A");graph.addVertex("A");
        graph.addVertex("B");
        graph.addVertex("C");
        graph.addVertex("D");
        graph.addVertex("E");

        // 添加边
        graph.addEdge("B", "A"); // B -> A
        graph.addEdge("C", "A"); // C -> A
        graph.addEdge("D", "B"); // D -> B
        graph.addEdge("E", "C"); // E -> C

        // 创建 ForkJoinPool
        ForkJoinPool pool = new ForkJoinPool();

        // 提交任务并获取目标节点的结果
        String targetNode = "A";
        int result = pool.invoke(new NodeTask(graph, targetNode));

        // 输出结果
        System.out.println("Result of target node " + targetNode + ": " + result);
    }

    // 节点任务类
    static class NodeTask extends RecursiveTask<Integer> {
        private final Graph<String, DefaultEdge> graph;
        private final String node;

        public NodeTask(Graph<String, DefaultEdge> graph, String node) {
            this.graph = graph;
            this.node = node;
        }

        @Override
        protected Integer compute() {
            System.out.println("Processing node: " + node);

            // 获取当前节点的所有来源节点
            Set<DefaultEdge> incomingEdges = graph.incomingEdgesOf(node);

            // 如果没有来源节点，直接返回当前节点的值（假设节点的值是节点名称的长度）
            if (incomingEdges.isEmpty()) {
                return node.length(); // 示例：返回节点名称的长度作为结果
            }

            // 遍历所有来源节点，创建子任务并获取结果
            int sum = 0;
            for (DefaultEdge edge : incomingEdges) {
                String sourceNode = graph.getEdgeSource(edge);

                // 创建子任务
                NodeTask subTask = new NodeTask(graph, sourceNode);
                subTask.fork(); // 异步执行子任务

                // 等待子任务完成并累加结果
                sum += subTask.join();
            }

            // 返回当前节点的结果（示例：来源节点结果之和 + 当前节点名称的长度）
            return sum + node.length();
        }
    }
}